<!-- 在线上传 -->
<template>
    <div class="container">
        <div style="padding: 10px 0; text-align: right">
            上传到：
            <el-select v-model="group_id" style="margin-left: 10px">
                <el-option v-for="group in groups"
                           :key="group.id"
                           :label="group.name"
                           :value="group.id"
                />
            </el-select>
        </div>
        <ul class="upload-action">
            <li>
                <el-button @click="onClickAddImage"
                           v-if="multi || (!multi && list.length === 0)">
                    添加图片
                </el-button>
            </li>
            <li>
                <span style="margin-right: 12px">
                    <span v-show="list.length">
                        共{{ list.length }}张图片
                    </span>
                        <span v-show="successCount">
                        <template v-if="list.length">，</template>
                        已上传{{ successCount }}
                    </span>
                </span>
                <el-button @click="onClickStart">开始上传</el-button>
            </li>
        </ul>
        <div class="upload-main">
            <vue-scroll>

                <template v-for="(item, idx) in list">
                    <div class="upload-main-item" :key="idx">
                        <div class="upload-main-close" @click="onClickRemoveUpload(idx)">
                            <i class="el-icon-close"></i>
                        </div>
                        <div class="upload-main-box">
                            <!-- 成功层 -->
                            <div v-if="item.state === state.success"
                                 class="upload-main-success"></div>
                            <div class="upload-main-image">
                                <img :src="item.preview" draggable="false"/>
                            </div>
                            <div class="upload-main-state"
                                 :class="{ 'error': hasError(item) }">
                                <template v-if="![state.uploading, state.success].includes(item.state)">
                                    {{ getStateMsg(item) }}
                                </template>

                                <el-progress v-else-if="item.state === state.uploading"
                                             :percentage="item.progress"
                                             :show-text="false"/>
                            </div>
                        </div>
                        <span class="upload-main-text">
                            {{ item.file.name }}
                        </span>
                    </div>
                </template>
            </vue-scroll>
        </div>
    </div>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
import { uploadImage } from '@/services/upload.service';
import { mapLimit } from 'async';
import { UploadDialogModule } from '@/components/app-upload/store';

enum State {
    wait,
    uploading,
    error,
    success,
}

export interface AppUploadImage {
    key: string;
    preview: string;
    file: File;
    state: State;
    message?: string;
    progress: number;
}

@Component({ name: 'AppUploadUpload' })
export default class AppUploadUpload extends Vue {
    @Prop({ type: Number, default: 3 }) readonly maxLimit!: number;
    private list: AppUploadImage[] = [];
    private group_id: number = 0;

    private get state() {
        return State;
    }

    private get groups() {
        return UploadDialogModule.groups;
    }

    private get multi(): boolean {
        return !!UploadDialogModule.info.multi;
    }

    // 删除准备上传的图片
    private onClickRemoveUpload(idx: number) {
        this.list.splice(idx, 1);
    }


    private get successCount(): number {
        return this.list.filter(e => e.state === State.success).length;
    }

    // 文件是否已存在
    private fileEqual(fs: File): boolean {
        return this.list.findIndex((f: AppUploadImage) => {
            return f.file.name == fs.name
                && f.file.lastModified == fs.lastModified
                && f.file.size == fs.size;
        }) > -1;
    }

    private hasError(item: AppUploadImage): boolean {
        return item.state === State.error;
    }

    private getStateMsg(item: AppUploadImage): string {
        switch (item.state) {
            case State.wait:
                return '';
            case State.uploading:
                return '正在上传';
            case State.error:
                return item.message ?? '';
            case State.success:
                return '上传完成';
            default:
                return '未知错误';
        }
    }

    // 添加图片
    private onClickAddImage() {
        let file = document.createElement('input');
        file.setAttribute('type', 'file');
        console.log('mmm', this.multi, UploadDialogModule.info)
        if (this.multi) {
            file.setAttribute('multiple', 'multiple');
        }
        file.click();

        file.onchange = (val: any) => {
            for (let i = 0; i < val.target.files.length; i++) {
                let len = this.list.length;
                let fs = val.target.files[i];
                let fileReader = new FileReader();
                if (this.fileEqual(fs)) {
                    console.log('重复文件')
                    continue;
                }
                fileReader.onload = (evt) => {
                    this.list.push({
                        key: `${i + len}`,
                        preview: evt?.target?.result as string,
                        file: fs,
                        state: State.wait,
                        progress: 0,
                    });
                }
                fileReader.readAsDataURL(fs);
            }
        }
    }

    // 开始上传
    private onClickStart() {
        if (this.list.length === 0) {
            this.$message.error('请添加图片');
            return;
        }
        mapLimit(this.list, this.maxLimit, this.uploadImage, this.uploadSuccess);
    }

    // 开始请求
    private uploadImage(item: AppUploadImage, callback: any) {
        item.state = State.uploading;
        uploadImage({
            group_id: this.group_id,
            file: item.file,
            onUploadProgress: (evt) => {
                const percent: number = Math.floor((100 * evt.loaded) / evt.total);
                item.progress = percent;
            }
        })
            .then(result => {
                item.state = State.success;
                callback(null, result.data);
            })
            .catch(err => {
                item.state = State.error;
                item.message = err.message;
                callback(null, null);
            })
    }

    // 上传完成
    private uploadSuccess(err: any, results: any[] | undefined) {
        if (results && results.filter(n => n).length) {
            results.forEach(f => {
                UploadDialogModule.addFile(f);
            });
            console.info(results);
        }
    }

    // 清除上传队列
    clearImages() {
        this.list = [];
    }
}
</script>

<style scoped lang="scss">
.upload {
    &-action {
        display: flex;
        justify-content: space-between;
    }
    &-main {
        padding: 20px;
        margin-top: 12px;
        height: 300px;
        border: solid 1px #efefef;
        overflow-y: auto;
        &-close {
            position: absolute;
            right: 5px;
            top: 0;
            cursor: pointer;
            z-index: 10;
            &:hover {
                color: #ffa556;
            }
        }
        &-item {
            text-align: center;
            display: inline-block;
            width: 105px;
            box-sizing: border-box;
            margin: 5px;
            position: relative;
        }
        &-box {
            height: 100px;
            padding: 10px;
            border: solid 1px #efefef;
            overflow: hidden;
            position: relative;
            &:hover {
                background: #E9EFF6;
                border: solid 1px #5690D2;
            }
        }
        &-image {
            flex: 1;
            height: 80px;
            img {
                width: 100%;
                height: 100%;
            }
        }
        &-state {
            padding: 3px 0;
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            overflow: hidden;
            &.error {
                color: #fff;
                background: #ff0000;
            }
        }
        // 上传成功
        &-success {
            position: absolute;
            right: 0;
            bottom: 0;
            width: 32px;
            height: 32px;
            background-image: url('../images/success.png');
            background-size: 100% 100%;
        }
        &-text {
            display: inline-block;
            font-size: 12px;
            height: 30px;
            line-height: 30px;
            overflow: hidden;
        }
    }
}
</style>
